package session;

import entity.Client;
import entity.IndicativeProductPrice;
import entity.Quotation;
import entity.QuotationItem;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import javax.ejb.LocalBean;
import javax.ejb.Stateful;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

/**
 *
 * @author Samuel
 */
@Stateful
@LocalBean
public class QuotationManager {

    @PersistenceContext
    private EntityManager em;
    private Quotation quotation;
    private QuotationItem quotationItem;
    private Collection<Quotation> quotationList = new ArrayList<Quotation>();
    private IndicativeProductPrice productPrice;
    private Collection<IndicativeProductPrice> productsList = new ArrayList<IndicativeProductPrice>();
    private Collection<Client> clients = new ArrayList<Client>();     //maybe to be removed when merged.

    public void createQuotation(Integer daysValid) {
        setQuotation(new Quotation());
        Date today = new java.util.Date();
        Timestamp dateTime = new Timestamp(today.getTime());
        getQuotation().setDateTime(dateTime);
        getQuotation().setDaysValid(daysValid);


    }

    public void createQuotation() {
        setQuotation(new Quotation());
        Date today = new java.util.Date();
        Timestamp dateTime = new Timestamp(today.getTime());
        getQuotation().setDateTime(dateTime);


    }

    public void addLeadTimeToQuotation(Long id, Integer indicativeLeadTime) {

        quotation = em.find(Quotation.class, id);
        quotation.setIndicativeLeadTime(indicativeLeadTime);
        quotation.setNeedLeadTime(Boolean.FALSE);
        if (quotation.getNeedDaysValid().equals(Boolean.FALSE)) {
            quotation.setStatus("Completed");
        } else {
            quotation.setStatus("Waiting for Days of Validity");
        }
        Date today = new java.util.Date();
        Timestamp dateTime = new Timestamp(today.getTime());
        quotation.setDateTime(dateTime);
        em.flush();
    }

    public void addDaysValidToQuotation(Long id, Integer daysValid) {

        quotation = em.find(Quotation.class, id);
        quotation.setDaysValid(daysValid);
        quotation.setNeedDaysValid(Boolean.FALSE);
        if (quotation.getNeedLeadTime().equals(Boolean.FALSE)) {
            quotation.setStatus("Completed");
        } else {
            quotation.setStatus("Waiting for Indicative Lead Time");
        }
        
        /* dateTime need not be reset when entering validity days? Will be done oer at inputting leadtime stage
        Date today = new java.util.Date();
        Timestamp dateTime = new Timestamp(today.getTime());
        quotation.setDateTime(dateTime);
         */

        em.flush();
    }

    public void editQuotation(Long quotationId, Integer indicativeLeadTime, Integer daysValid, String status, Boolean needDaysValid, Boolean needLeadTime, Long clientId) {

        quotation = em.find(Quotation.class, quotationId);
        quotation.setIndicativeLeadTime(indicativeLeadTime);
        quotation.setNeedLeadTime(needLeadTime);
        quotation.setStatus(status);
        quotation.setDaysValid(daysValid);
        quotation.setNeedDaysValid(needDaysValid);
        Date today = new java.util.Date();
        Timestamp dateTime = new Timestamp(today.getTime());
        quotation.setDateTime(dateTime);
        quotation.setClient(this.getClient(clientId));

        Double temp = calculateTotalPrice(quotationId);
        temp = (Math.round(temp * 100)) / 100.0;
        quotation.setTotalPrice(temp);
        em.flush();
    }

    public void addQuotationItem(String productName, Integer numOfProduct, Double itemProductPrice) {
        setQuotationItem(new QuotationItem());
        getQuotationItem().setProductName(productName);
        getQuotationItem().setNumOfProduct(numOfProduct);
        getQuotationItem().setProductPrice(itemProductPrice);
        getQuotation().getQuotationItems().add(getQuotationItem());

    }

    public void editAddQuotationItem(Long quotationId, String productName, Integer numOfProduct, Double itemProductPrice) {
        setQuotationItem(new QuotationItem());
        getQuotationItem().setProductName(productName);
        getQuotationItem().setNumOfProduct(numOfProduct);
        getQuotationItem().setProductPrice(itemProductPrice);
        quotation = em.find(Quotation.class, quotationId);
        quotation.getQuotationItems().add(getQuotationItem());

        em.flush();
    }

    public void deleteQuotationItem(Long quotationId, Long quotationItemId) {
        Collection<QuotationItem> itemsList;
        quotation = getQuotation(quotationId);
        itemsList = quotation.getQuotationItems();
        for (Object o : itemsList) {
            QuotationItem temp = (QuotationItem) o;
            if (temp.getId().equals(quotationItemId)) {
                itemsList.remove(temp);
                break;
            }
        }
        quotation.setQuotationItems(itemsList);
        quotationItem = em.find(QuotationItem.class, quotationItemId);
        em.remove(quotationItem);

        em.flush();
    }

    public void editQuotationItem(Long quotationItemId, Integer quantity) {
        quotationItem = em.find(QuotationItem.class, quotationItemId);
        quotationItem.setNumOfProduct(quantity);
      

        em.flush();
    }

    public void persistQuotation() {
        Double temp = calculateTotalPrice();
        temp = (Math.round(temp * 100)) / 100.0;
        quotation.setTotalPrice(temp);
        em.flush();
        quotation.setTotalPrice(temp);
        em.persist(getQuotation());
        em.flush();
    }

    public Quotation getQuotation() {
        return quotation;
    }

    public Quotation getQuotation(Long id) {
        Quotation q;
        q = getEm().find(Quotation.class, id);

        return q;
    }

    public Collection<QuotationItem> getQuotationItems(Long id) {
        Quotation q;
        q = getEm().find(Quotation.class, id);
        return q.getQuotationItems();

    }

    public Collection<QuotationItem> getQuotationItems() {

        return quotation.getQuotationItems();

    }

    /**
     * @return the quotationList
     */
    public Collection<Quotation> getQuotationList() {
        quotationList = new ArrayList<Quotation>();
        Query q = getEm().createQuery("Select q From Quotation q");
        for (Object o : q.getResultList()) {
            Quotation temp = (Quotation) o;
            quotationList.add(temp);
        }
        return quotationList;
    }

    public Collection<Quotation> getQuotationList(Long clientId) {
        quotationList = new ArrayList<Quotation>();
        Query q = getEm().createQuery("Select q From Quotation q");
        for (Object o : q.getResultList()) {
            Quotation temp = (Quotation) o;
            if (temp.getClient().getId().equals(clientId)) {
                quotationList.add(temp);
            }
        }
        return quotationList;
    }

    public Collection<Quotation> getNeedLeadTimeQuotationList() {
        quotationList = new ArrayList<Quotation>();
        Query q = getEm().createQuery("Select q From Quotation q Where q.needLeadTime = true");
        for (Object o : q.getResultList()) {
            Quotation temp = (Quotation) o;
            quotationList.add(temp);
        }
        return quotationList;
    }

    public Collection<Quotation> getNeedValidityDaysQuotationList() {
        quotationList = new ArrayList<Quotation>();
        Query q = getEm().createQuery("Select q From Quotation q Where q.needDaysValid = true");
        for (Object o : q.getResultList()) {
            Quotation temp = (Quotation) o;
            quotationList.add(temp);
        }
        return quotationList;
    }

    /*
    public void mergeQuotation(Quotation q) {
    getEm().merge(q);
    getEm().flush();
    }
     */
    public Double calculateTotalPrice(Long quotationId) {
        Quotation q = getQuotation(quotationId);
        Double tempTotal = 0.0;
        for (Object o : q.getQuotationItems()) {
            QuotationItem temp = (QuotationItem) o;
            tempTotal += temp.getProductPrice() * temp.getNumOfProduct();
        }
        return tempTotal;
    }

    public Double calculateTotalPrice() {

        Double tempTotal = 0.0;
        for (Object o : quotation.getQuotationItems()) {
            QuotationItem temp = (QuotationItem) o;
            tempTotal += temp.getProductPrice() * temp.getNumOfProduct();
        }
        return tempTotal;
    }

    //may be deleted/copied to ClientManager when merged with other people
    public Client getClient(Long id) {
        Client c;
        c = getEm().find(Client.class, id);

        return c;
    }

    /*COMMENT OFF UNTIL INTEGRATION, UNTESTED CODE
    //may be deleted/copied to ClientManager when merged with other people
    public Client getClient(String username) {
    Client c;
    Query q = getEm().createQuery("Select c From Client c");
    for (Object o : q.getResultList()) {
    Client temp = (Client) o;
    if(temp.getStaffAccount().getUsername().equals(username))
    c = temp;
    }
    
    return c;
    }
     */
    //may be deleted/copied to ClientManager when merged with other people
    public Collection<Client> getClients() {

        clients = new ArrayList<Client>();
        Query q = getEm().createQuery("Select c From Client c");
        for (Object o : q.getResultList()) {
            Client temp = (Client) o;
            clients.add(temp);
        }
        return clients;
    }
public Collection<Quotation> getCompletedQuotationList() {
        quotationList = new ArrayList<Quotation>();
        Query q = getEm().createQuery("Select q From Quotation q Where q.daysValid is not null AND q.indicativeLeadTime is not NULL");
        for (Object o : q.getResultList()) {
            Quotation temp = (Quotation) o;
            quotationList.add(temp);
        }
        return quotationList;
    }
    
        public Collection<Quotation> getClientCompletedQuotationList(Long clientId) {
        quotationList = new ArrayList<Quotation>();
        Query q = getEm().createQuery("Select q From Quotation q Where q.daysValid is not null AND q.indicativeLeadTime is not NULL");
        for (Object o : q.getResultList()) {
            Quotation temp = (Quotation) o;
            if (temp.getClient().getId().equals(clientId)) {
                quotationList.add(temp);
            }
        }
        return quotationList;
    }
    /**
     * @return the em
     */
    public EntityManager getEm() {
        return em;
    }

    /**
     * @param em the em to set
     */
    public void setEm(EntityManager em) {
        this.em = em;
    }

    /**
     * @param quotation the quotation to set
     */
    public void setQuotation(Quotation quotation) {
        this.quotation = quotation;
    }

    /**
     * @return the quotationItem
     */
    public QuotationItem getQuotationItem() {
        return quotationItem;
    }

    public QuotationItem getQuotationItem(Long id) {
        quotationItem = em.find(QuotationItem.class, id);
        return quotationItem;
    }

    /**
     * @param quotationItem the quotationItem to set
     */
    public void setQuotationItem(QuotationItem quotationItem) {
        this.quotationItem = quotationItem;
    }

    /**
     * @param quotationList the quotationList to set
     */
    public void setQuotationList(Collection<Quotation> quotationList) {
        this.quotationList = quotationList;
    }

    /**
     * @return the productPrice
     */
    public IndicativeProductPrice getProductPrice() {
        return productPrice;
    }

    /**
     * @param productPrice the productPrice to set
     */
    public void setProductPrice(IndicativeProductPrice productPrice) {
        this.productPrice = productPrice;
    }

    /**
     * @param productsList the productsList to set
     */
    public void setProductsList(Collection<IndicativeProductPrice> productsList) {
        this.productsList = productsList;
    }

    /**
     * @param clients the clients to set
     */
    public void setClients(Collection<Client> clients) {
        this.clients = clients;
    }
}
